package com.gz.seckill.util;

import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;

public class JedisPoolUtil {

    //volatile的作用
    //1. 线程的可见性: 当一个线程去修改一个共享变量时，另外一个线程可以读取这个修改的值
    //2. 顺序的一致性: 禁止指令重排，例如两个线程一起操作一个数，操作顺序不一样结果可能不一样
    //volatile保证顺序的一致性，例如408里面的多线程操作a,获得多少种结果的那种题目。
    private static volatile JedisPool jedisPool = null;

    private JedisPoolUtil() {

    }

    //保证每次调用返回的JedisPool是单例的
    public static JedisPool getJedisPoolInstance() {

        if (null == jedisPool) {
            //若多个线程同时请求，用synchronized进行同步
            synchronized (JedisPoolUtil.class) {
                //双重校验，因为synchronized只保证同步
                //但第一个完成之后,同步锁释放,jedisPool就不为空了，后面的那就不需要再继续执行了
                //用来保证单例
                if (null == jedisPool) {

                    JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
                    //对连接池进行配置
                    jedisPoolConfig.setMaxIdle(32);
                    jedisPoolConfig.setMaxTotal(200);
                    jedisPoolConfig.setMaxWaitMillis(60 * 1000);
                    jedisPoolConfig.setBlockWhenExhausted(true);
                    jedisPoolConfig.setTestOnBorrow(true);
                    jedisPool = new JedisPool(jedisPoolConfig, "192.168.131.135", 6379,60000,"foobared");
                }
            }
        }
        return jedisPool;
    }

    //释放连接资源
    public static void release(Jedis jedis) {
        if (jedis != null) {
            jedis.close();//如果jedis是从jedisPool获取的，jedis.close()就是将jedis连接放回连接池
        }
    }
}
